home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 25
/
Cream of the Crop 25.iso
/
doom
/
quake_ad.zip
/
BSP2M011.ZIP
/
BSP2M010.C
next >
Wrap
C/C++ Source or Header
|
1997-01-16
|
10KB
|
371 lines
#include "cmdlib.h"
#include "mathlib.h"
#include "bspfile.h"
#include "mathlib.h"
#define MAX_FACE_EDGES 20
typedef struct epair_s
{
struct epair_s *next;
char *key;
char *value;
} epair_t;
float b2m_ver = (float)0.1; // BSP2MAP version
int verbose1, verbose2, verbose3 = 0;
//--------------
void GetEdges(int ledge, dedge_t *edge)
{
if (dsurfedges[ledge]>0) {
*edge = dedges[dsurfedges[ledge]];
} else {
edge->v[0] = dedges[-dsurfedges[ledge]].v[1];
edge->v[1] = dedges[-dsurfedges[ledge]].v[0];
}
}
void ProcessFace(int face)
{
short n_face_edges;
int ledge, ledge2;
dedge_t edges[MAX_FACE_EDGES];
dvertex_t vert_beg[MAX_FACE_EDGES];
dvertex_t vert_end[MAX_FACE_EDGES];
vec3_t normal, v1, v2, v3;
miptex_t *p_miptex;
dmiptexlump_t *head_miptex;
texinfo_t *p_texinfo;
float x_off, y_off, rotation, x_scale, y_scale;
static int gi=0;
char gs[12];
char texname[18];
n_face_edges = dfaces[face].numedges;
if (n_face_edges < 3)
Error ("too few edges for face");
if (n_face_edges > MAX_FACE_EDGES)
Error ("too many edges for face");
for (ledge=0; ledge < n_face_edges; ledge++) {
GetEdges(ledge + dfaces[face].firstedge, &edges[ledge]);
vert_beg[ledge] = dvertexes[edges[ledge].v[0]];
vert_end[ledge] = dvertexes[edges[ledge].v[1]];
if (verbose1)
printf(" // edge %d, ledge %d [%4.2f %4.2f %4.2f] [%4.2f %4.2f
%4.2f]\n",
ledge, ledge + dfaces[face].firstedge,
vert_beg[ledge].point[0], vert_beg[ledge].point[1],
vert_beg[ledge].point[2],
vert_end[ledge].point[0], vert_end[ledge].point[1],
vert_end[ledge].point[2]);
}
_VectorCopy(dplanes[dfaces[face].planenum].normal, normal);
if (verbose1) {
printf(" // dfaces[face].planenum = %d, side = %d\n",
dfaces[face].planenum, dfaces[face].side);
printf(" // normal ( %4.2f %4.2f %4.2f ) type %d\n",
normal[0], normal[1], normal[2],
dplanes[dfaces[face].planenum].type);
}
VectorScale (normal, (float)2, normal);
if (!dfaces[face].side)
VectorInverse(normal);
for (ledge2=1; ledge2 < n_face_edges-2; ledge2++) {
_VectorSubtract(vert_end[0].point, vert_beg[0].point, v1);
_VectorSubtract(vert_end[ledge2].point, vert_beg[ledge2].point, v2);
VectorNormalize(v1);
VectorNormalize(v2);
if (!VectorCompare(v1, v2))
break;
}
head_miptex = (dmiptexlump_t *)dtexdata;
p_texinfo = &texinfo[dfaces[face].texinfo];
p_miptex = (miptex_t *)((((byte
*)dtexdata))+(head_miptex->dataofs[p_texinfo->miptex]));
strcpy(texname, p_miptex->name);
strupr(texname);
if (verbose2)
printf(" // texinfo ( %4.2f %4.2f %4.2f %4.2f ) ( %4.2f %4.2f %4.2f
%4.2f )\n",
p_texinfo->vecs[0][0], p_texinfo->vecs[0][1],
p_texinfo->vecs[0][2], p_texinfo->vecs[0][3],
p_texinfo->vecs[0][0], p_texinfo->vecs[0][1],
p_texinfo->vecs[0][2], p_texinfo->vecs[0][3]);
//here must calc x_off y_off rotation x_scale y_scale from p_texinfo->vecs !
x_off = y_off = rotation = (float)0;
x_scale = y_scale = (float)1;
printf(" {\n");
printf(" ( %4.0f %4.0f %4.0f ) ( %4.0f %4.0f %4.0f ) ( %4.0f %4.0f %4.0f )
%s %.0f %.0f %.0f %.2f %.2f\n",
vert_beg[0].point[0], vert_beg[0].point[1], vert_beg[0].point[2],
vert_end[0].point[0], vert_end[0].point[1], vert_end[0].point[2],
vert_end[ledge2].point[0], vert_end[ledge2].point[1],
vert_end[ledge2].point[2],
texname,
x_off, y_off, rotation, x_scale, y_scale);
for (ledge=0; ledge < n_face_edges; ledge++) {
if (ledge==0) {
_VectorSubtract(vert_end[n_face_edges-1].point,
vert_beg[n_face_edges-1].point, v1);
_VectorSubtract(vert_end[ledge].point, vert_beg[ledge].point, v2);
VectorNormalize(v1);
VectorNormalize(v2);
if (VectorCompare(v1, v2))
continue;
} else {
_VectorSubtract(vert_end[ledge-1].point, vert_beg[ledge-1].point,
v1);
_VectorSubtract(vert_end[ledge].point, vert_beg[ledge].point, v2);
VectorNormalize(v1);
VectorNormalize(v2);
if (VectorCompare(v1, v2))
continue;
}
_VectorAdd(vert_end[ledge].point, normal, v2);
printf(" ( %4.0f %4.0f %4.0f ) ( %4.0f %4.0f %4.0f ) ( %4.0f %4.0f
%4.0f ) %s 0 0 0 1 1\n",
vert_end[ledge].point[0], vert_end[ledge].point[1],
vert_end[ledge].point[2],
vert_beg[ledge].point[0], vert_beg[ledge].point[1],
vert_beg[ledge].point[2],
v2[0], v2[1], v2[2],
texname);
}
_VectorAdd(vert_beg[0].point, normal, v2);
_VectorAdd(vert_end[0].point, normal, v1);
_VectorAdd(vert_end[ledge2].point, normal, v3);
if (verbose3)
sprintf(gs, "tx%04x", gi++);
printf(" ( %4.0f %4.0f %4.0f ) ( %4.0f %4.0f %4.0f ) ( %4.0f %4.0f %4.0f )
%s 0 0 0 1 1\n",
v1[0], v1[1], v1[2],
v2[0], v2[1], v2[2],
v3[0], v3[1], v3[2],
!verbose3 ? texname : gs);
printf(" }\n");
}
void ProcessModel(int model)
{
int face;
printf(" // total brushes: %d\n", dmodels[model].numfaces);
for (face=0; face < dmodels[model].numfaces; face++)
ProcessFace(face + dmodels[model].firstface);
}
#define MAXTOKEN 128
char token[MAXTOKEN];
qboolean unget;
char *script_p;
int scriptline;
epair_t epair;
void StartTokenParsing (char *data) // this function comes from qbsp\map.c
{
scriptline = 1;
script_p = data;
unget = false;
}
qboolean GetToken (qboolean crossline) // this function comes from qbsp\map.c
{
char *token_p;
if (unget) // is a token allready waiting?
return true;
//
// skip space
//
skipspace:
while (*script_p <= 32)
{
if (!*script_p)
{
if (!crossline)
Error ("Line %i is incomplete",scriptline);
return false;
}
if (*script_p++ == '\n')
{
if (!crossline)
Error ("Line %i is incomplete",scriptline);
scriptline++;
}
}
if (script_p[0] == '/' && script_p[1] == '/') // comment field
{
if (!crossline)
Error ("Line %i is incomplete\n",scriptline);
while (*script_p++ != '\n')
if (!*script_p)
{
if (!crossline)
Error ("Line %i is incomplete",scriptline);
return false;
}
goto skipspace;
}
//
// copy token
//
token_p = token;
if (*script_p == '"')
{
script_p++;
while ( *script_p != '"' )
{
if (!*script_p)
Error ("EOF inside quoted token");
*token_p++ = *script_p++;
if (token_p > &token[MAXTOKEN-1])
Error ("Token too large on line %i",scriptline);
}
script_p++;
}
else while ( *script_p > 32 )
{
*token_p++ = *script_p++;
if (token_p > &token[MAXTOKEN-1])
Error ("Token too large on line %i",scriptline);
}
*token_p = 0;
return true;
}
void UngetToken () // this function comes from qbsp\map.c
{
unget = true;
}
void _ParseEpair (void)
{
memset (&epair, 0, sizeof(epair_t));
if (strlen(token) >= MAX_KEY-1)
Error ("ParseEpar: token too long");
epair.key = copystring(token);
GetToken (false);
if (strlen(token) >= MAX_VALUE-1)
Error ("ParseEpar: token too long");
epair.value = copystring(token);
}
int ParseEnt(void)
{
int model;
int keys;
model = -1;
keys = 0;
if (!GetToken (true))
return -2;
if (strcmp (token, "{") )
Error ("ProcessEnts: { not found");
do {
if (!GetToken (true))
Error ("ParseEnt: EOF without closing brace");
if (!strcmp (token, "}") )
break;
_ParseEpair();
if (!keys) {
keys++;
printf ("{\n");
}
if (!strcmp(epair.key, "model")) {
model = atoi(&epair.value[1]);
if (verbose1 || verbose2 || verbose3)
printf (" // \"%s\" \"%s\"\n", epair.key, epair.value);
} else {
printf (" \"%s\" \"%s\"\n", epair.key, epair.value);
}
if (!strcmp(epair.key, "classname") && !strcmp(epair.value,
"worldspawn")) {
model = 0;
}
} while (1);
if (model >= 0)
ProcessModel(model);
if (keys)
printf ("}\n");
return model;
}
void MakeMap (void)
{
int model;
StartTokenParsing(dentdata);
while (1) {
model = ParseEnt();
if (model == -2)
break;
}
}
//--------------
void main (int argc, char **argv)
{
int i;
char source[1024];
double start, end;
for (i=1 ; i<argc ; i++) {
if (!strcmp(argv[i], "-v1")) {
printf ("//verbose1 = true\n");
verbose1 = 1;
}
else if (!strcmp(argv[i], "-v2")) {
printf ("//verbose2 = true\n");
verbose2 = 1;
}
else if (!strcmp(argv[i], "-v3")) {
printf ("//verbose3 = true\n");
verbose3 = 1;
}
else if (argv[i][0] == '-')
Error ("Unknown option \"%s\"", argv[i]);
else
break;
}
if (i != argc - 1) {
printf ("BSP2MAP %.2f Created by Janis Jagars (Disastry)\n", b2m_ver);
Error ("usage: bsp2map [-v1] [-v2] [-v3] bspfile > mapfile");
}
start = I_FloatTime ();
printf ("//---------------------\n");
strcpy (source, argv[i]);
DefaultExtension (source, ".bsp");
printf ("//Created from %s by BSP2MAP %.2f\n", source, b2m_ver);
LoadBSPFile (source);
MakeMap ();
end = I_FloatTime ();
printf ("//%5.1f seconds elapsed\n", end-start);
printf ("//---------------------\n");
}